;	PDP-11 FLOATING POINT  PACKAGE
;	FLOATING POINT ADD
;	FLOATING POINT SUBTRACT
;	FLOATING POINT MULTIPLY
;	FLOATING POINT DIVIDE
;	FLOATING POINT NEGATE
;	FLOATING POINT NORMALIZATION
;
;	MODULES INCLUDED:
;	1. ADDF
;	2. SUBF
;	3. MULF
;	4. DIVF
;	5. NEGF
;	6. NORM
;
;
;
;
R0	=	%0
R1	=	%1
R2	=	%2
R3	=	%3
R4	=	%4
R5	=	%5
SP	=	%6
PC	=	%7
ADDF:	MOV	R0,-(SP)	;SAVE DEFA
	MOV	(R1)+,-(SP)	;MOVE SOURCE TO STACK
	MOV	(R1)+,-(SP)
	MOV	@R1,-(SP)
	MOV	(R0)+,R2	;MOVE DESTINATION TO R2,R1,R0
	MOV	(R0)+,R1
	MOV	@R0,R0
	CMP	R0,@SP		;IF EXPB>EXPA SWAP
	BLOS	M.FAD2		;FLOATING POINT NUMBERS
	MOV	SP,R4	
	MOV	R0,R3
	MOV	@R4,R0
	MOV	R3,(R4)+
	MOV	R1,R3
	MOV	@R4,R1
	MOV	R3,(R4)+
	MOV	R2,R3
	MOV	@R4,R2
	MOV	R3,(R4)+
M.FAD2:	SUB	@SP,R0		;EXPB=EXPB-EXPA
	BEQ	M.FAD8		;IF ZERO DIFERENCE THEN QUICKLY
	BPL	M.FAD3		;IF POSITIVE OMIT ADD
	CMP	R0,#-37
	BGE	M.FAD4
M.FAD3:	MOV	2(SP),R5
	MOV	4(SP),R3
	BR	M.FAD7
M.FAD4:	CMP	R0,#-20		;IF DIFFERENCE BETWEEN EXPONENTS IS
				;>16 AND <31 DO A FAST RIGHT SHIFT
	BGT	M.FAD5		;ADD 15 TO THE EXPONENT,MOVE HIGH TO
	ADD	#20,R0
	MOV	R1,R2
	CLR	R1
	TST	R2
	BPL	M.FAD5
	COM	R1
M.FAD5:	TST	R0		;IF DIFFERENCE BETWEEN EXPONENTS IS 0
				;THEN SKIP R3IGNMENT LOOP
	BEQ	M.FAD8
M.FAD6:	ASR	R1		;SHIFT FRACTION RIGHT  AND CHECK
	ROR	R2		;IF EXPONENTS ARE ALIGNED YET
	INC	R0
	BNE	M.FAD6
M.FAD8:	MOV	2(SP),R5	;PUT FRACTION A INTO REGISTERS
	MOV	4(SP),R3
	ADD	R2,R3		;DO A DOUBLE PRECISION ADD TO SUM
	ADC	R5		;THE FRACTIONS
	BVS	M.FAD9		;JUMP IF V BIT ON
	ADD	R1,R5
	BVC	.+10	;->	 IF AN OVERFLOW OCCURS
M.FAD1:	ROR	R5	;  I	 THEN SHIFT THE CARRY BIT
	ROR	R3	;  I	 BACK INTO THE NUMBER AND
	INC	@SP	;  I	 INCREMENT THE EXPONENT
M.FAD7:	MOV	6(SP),R0;<-	 PUT DEFA IN A REGISTER
	MOV	R0,R1		;SAVE DEFA FOR LATER
	MOV	R3,(R0)+	;MOVE FRACTION TO DESTINATION
	MOV	R5,(R0)+
	MOV	@SP,(R0)+
	MOV	R1,R0		;GET UN TOUCHED DEFA
	ADD	#10,SP		;FIX UP STACK
	JMP	NORM
M.FAD9:	ADD	R1,R5		;ADD THE HIGHORDER FRACTIONS
	BCS	M.FAD7		;IF CARRY NO REAL OVERFLOW
	BR	M.FAD1		;ELSE SHIFT RIGHT
SUBF:	MOV	R0,R4		;SAVE DEFA
	SUB	#6,SP
	MOV	SP,R0
	JSR	PC,NEGF		;NEGATE
	MOV	R4,R0
	MOV	SP,R1
	JSR	PC,ADDF		;AND ADD
	ADD	#6,SP
	CLV			;MAYBE OVERFLOW ON BIG MACHINE
	RTS	PC




NEGF:	MOV	(R1)+,R2	;MOVE SOURCE FRACTION TO REGISTERS
	MOV	(R1)+,R3	
	NEG	R3		;NEGATE FRACTION IN REGISTERS
	NEG	R2
	SBC	R3
	MOV	R2,(R0)+	;MOVE NEGATIVE FRACTION TO DESTINATION
	MOV	R3,(R0)+
	MOV	(R1)+,(R0)+	;MOVE EXPONENT TO DESTINATION
	RTS	PC
DIVF:	MOV	R0,-(SP)	;SAVE DEFA
	CLR	-(SP)		;SIGN CONTROL WORD
	MOV	(R1)+,R5	;PICK UP THE DIVISOR
	MOV	(R1)+,R4	;HIGH ORDER WORD
	BEQ	M.DIVV		;DIVISION BY ZERO IS A NO-NO
	BGT	.+12	;->	IF NEGATIVE
	NEG	R4	;  I	CHANGE THE SIGN
	NEG	R5	;  I	BUT STILL KEEP
	SBC	R4	;  I	TRACK OF THE ORIGINAL
	INC	@SP	;  I	SIGN ON THE STACK
	MOV	(R0)+,R3;<-
	MOV	(R0)+,R2	;PICK UP THE DIVIDEND
	BEQ	M.MUL0		;REAL FAST IF ZERO HUH?
	BGT	.+12	;->	IF NEGATIVE
	NEG	R2	;  I	CHANGE THE SIGN
	NEG	R3	;  I	BUT STILL KEEP
	SBC	R2	;  I	TRACK OF THE ORIGINAL
	DEC	@SP	;  I	SIGN ON THE STACK WORD
	MOV	@R1,R1		;GET THE EXPONENTS
	NEG	R1		;AND TRY TO FORM THE NEW ONE
	ADD	@R0,R1
	ROR	R1		;TO CHECK FOR OVER-UNDER-FLOW
	ROL	R1
	BVC	M.DIVV
	ADD	#100000,R1
	MOV	R1,-(SP)	;AND PUT IT ON THE STACK
	MOV	R3,R1
	MOV	R2,R0
	CLR	R2		;SET UP TO DO THE DIVIDE
	CLR	R3
	ROR	R0
	ROR	R1		;DIVIDE BY TO TO AVOID OVERFLOW
	ROR	R2
	JSR	PC,M.DPID	;CALL THE DIVIDE ROUTINE
	NEG	R4		;CHANGE THE SIGN OF THE DIVISOR
	NEG	R5
	SBC	R4
	ASL	R1		;DOUBLE THE REMAINDER
	ROL	R0
	ADD	R5,R1		;ADD -(DIVISOR)
	ADC	R0
	ADD	R4,R0
	BLT	M.DIV2		;IF NEGATIVE REMAINDER> 1/2 DIVISOR
	ADD	#1,R3		;ROUND UP THE RESULT
	ADC	R2
				;ROUNDING COMPLETE
M.DIV2:	CLC
	ROR	R2		;CORRECT FOR DIVIDE BY TWO ABOVE
	ROR	R3
	INC	@SP
M.DIV6:	TST	2(SP)		;CHECK SIGN  WORD
	BEQ	.+10	;->
	NEG	R2	;  I
	NEG	R3	;  I
	SBC	R2	;  I
	MOV	4(SP),R0;<-	 GET DEFA
	MOV	R3,(R0)+
	MOV	R2,(R0)+
	MOV	(SP)+,@R0
M.DIR2:	CMP	(SP)+,(SP)+	;FIX UP THE STACK POINTER
	CMP	-(R0),-(R0)	;RETURN THE POINTER TO THE DEFA
	MOV	R0,R1		;SET DEFA = SEFA
	JMP	NORM		;GO NORMALIZE THE NUMBER
M.DIVV:	CMP	(SP)+,(SP)+	;FIX UP THE STACK
	SEV			;SET OVERFLOW AND GO
	RTS	PC
MULF:	MOV	R0,-(SP)	;SAVE DEFA
	MOV	(R1)+,R5	;FETCH SOURCE
	MOV	(R1)+,R4
	MOV	@R1,R1
	CLR	-(SP)		;SIGN CONTROL WORD
	TST	R4
	BEQ	M.MUL0		;SHORT CIRCUIT IF ZERO
	BGT	M.MUL2		;IF NEG MAKE POSITIVE
	NEG	R4		;ZIP-ZAP-
	NEG	R5		;ZOWIE-AND-
	SBC	R4		;SWOSH
	DEC	@SP		;FIDDLE WHITH THE SIGN
M.MUL2:	MOV	(R0)+,R3	;PICK UP DESTINATION
	MOV	(R0)+,R2
	BEQ	M.MUL0
	BGT	M.MUL3		;OMIT SIGN CHANGE IF POSITIVE
	NEG	R2
	NEG	R3
	SBC	R2
	INC	@SP		;DO A GOOD JOB ON THE SIGN
M.MUL3:	ADD	@R0,R1		;COMPUTE A TRY AT THE NEW EXPONENT
	ROR	R1		;HANDLE OVER-UNDER FLOW
	ROL	R1
	BVC	M.DIVV
	ADD	#100000,R1
	MOV	R1,-(SP)
	JSR	PC,M.DPIM	;DO THE MULTIPLACATION
	INC	@SP		;ADJUST THE EXPONENT AFTER MULTIPLY
M.MUL8:	ROL	R2		;NOW NORMALIZE
	ROL	R1
	ROL	R0
	BVS	M.MUL4
	DEC	@SP
	BR	M.MUL8
M.MUL4:	ROR	R0
	ROR	R1
M.MUL5:	ADC	R1		;ROUND OFF THE RESULT
	ADC	R0
	BVC	M.MUL6
	INC	@SP
	BR	M.MUL4
M.MUL6:	MOV	(SP)+,R2	;DO THE FANCY FOOT WORK
	TST	(SP)+		;REMEMBER THE SIGN WORD WE SAVED?
	BEQ	M.MUL7		;BRANCH FOR POSITIVE RESULT
	NEG	R0
	NEG	R1
	SBC	R0
M.MUL7:	MOV	(SP)+,R3	;WE SAVED THE DESTINATION FOR JUST SUCH A CAUSE
	MOV	R1,(R3)+
	MOV	R0,(R3)+
	MOV	R2,@R3
	RTS	PC		;RETURN TO THE CALLER
M.MUL0:	CLR	R0		;QUICK AND DIRTY
	CLR	R1
	CLR	R2
	TST	(SP)+		;GET RID OF THE SIGN CONTROL WORD
	BR	M.MUL7
NORM:	MOV	(R1)+,R4	;MOVE SOURCE TO REGISTERS
	MOV	(R1)+,R2
	MOV	@R1,R3
	MOV	R3,R5
	TST	R2		;CHECK FOR A ZERO FRACTION
	BNE	M.NOR2
	TST	R4
	BNE	M.NOR2
	CLR	R3		;RETURN 0.0 CAUSE FRACTION=0
	BR	M.RET2
M.NOR2:	INC	R3
M.NORL:	DEC	R3		;NORMALIZATION LOOP
	ASL	R4		;SHIFT FRACTION LEFT
	ROL	R2
	BVC	M.NORL		;NORMALIZED YET?
	BCC	M.NOR3		;SPECIAL -1 FRACTION CHECK
	TST	R2
	BNE	M.NOR4
	SEC			;IT WAS -1 TO MAKE IT -1/2
	ROR	R2
	INC	R5		;TO AVOID THE OVERFLOW PROBLEM
	INC	R3
M.NOR4:	SEC
M.NOR3:	ROR	R2
	ROR	R4
M.RET2:	MOV	R4,(R0)+
	MOV	R2,(R0)+
	MOV	R3,@R0
	CMP	R3,R5
	BHI	.+6	;->
	CLV		;  I
	RTS	PC	;  I
	SEV		;<-
	RTS	PC	;
	.EOT
                                                                                                                                                                                      